package com.yingxin.yxerp.module.print.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yingxin.yx.framework.commons.exception.BizException;
import com.yingxin.yx.framework.commons.id.IdHelper;
import com.yingxin.yx.framework.user.core.IUserSupport;
import com.yingxin.yx.framework.user.dto.UserDto;
import com.yingxin.yxerp.module.print.constant.PrintLimitTypeConst;
import com.yingxin.yxerp.module.print.constant.PrintStatusConst;
import com.yingxin.yxerp.module.print.entity.PrintApply;
import com.yingxin.yxerp.module.print.entity.PrintBusinessStat;
import com.yingxin.yxerp.module.print.entity.PrintLimit;
import com.yingxin.yxerp.module.print.entity.PrintRecord;
import com.yingxin.yxerp.module.print.entity.dto.PrintInfo;
import com.yingxin.yxerp.module.print.mapper.PrintRecordMapper;
import com.yingxin.yxerp.module.print.service.IPrintApplyService;
import com.yingxin.yxerp.module.print.service.IPrintBusinessStatService;
import com.yingxin.yxerp.module.print.service.IPrintLimitService;
import com.yingxin.yxerp.module.print.service.IPrintRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 打印记录 服务实现类
 * @author fanchao
 * @since 2022-02-19
 */

@Service
public class PrintRecordServiceImpl extends ServiceImpl<PrintRecordMapper, PrintRecord> implements IPrintRecordService {

    @Autowired
    private IUserSupport userSupport;

    @Autowired
    private IPrintBusinessStatService printBusinessStatService;

    @Autowired
    private IPrintApplyService printApplyService;

    @Autowired
    private IPrintLimitService printLimitService;

    @Override
    public PrintInfo checkPrint(String businessId, String businessNo, String businessType) {
        if (StringUtils.isBlank(businessId)) {
            throw new BizException("打印错误");
        }
        PrintLimit printLimit = printLimitService.getById(businessType);
        if (printLimit != null) {
            if (PrintLimitTypeConst.LIMIT_N.equals(printLimit.getLimitType())) {
                throw new BizException("打印被禁止");
            }
        }
        UserDto user = userSupport.getUser();
        if (user == null) {
            throw new BizException("未登录");
        }
        Date printTime = new Date();
        // PrintBusinessStat
        PrintBusinessStat printBusiness = printBusinessStatService.getById(businessId);
        if (printBusiness != null) {
            // 审核后可打印
            if (PrintStatusConst.AFTER_APPROVED.equals(printBusiness.getPrintStatus())) {
                throw new BizException("审核后可打印");
            }
            // 已经受限
            if (PrintStatusConst.LIMITED.equals(printBusiness.getPrintStatus())) {
                // 查询待打印申请
                PrintApply apply = printApplyService.getWaitingPrintApply(businessId, businessType, user.getUserId());
                if (apply == null) {
                    throw new BizException("已超过可打印份数");
                }
            }
        }
        // PrintInfo
        PrintInfo printInfo = new PrintInfo();
        printInfo.setId(IdHelper.snowflakeId());
        printInfo.setPrinterId(user.getUserId());
        printInfo.setPrintTime(printTime);
        printInfo.setBusinessId(businessId);
        printInfo.setBusinessType(businessType);
        printInfo.setBusinessNo(businessNo);
        // 本次不限制
        printInfo.setPrintStatus(PrintStatusConst.PRINTABLE);
        printInfo.setPrinterName(user.getStaffName());
        return printInfo;
    }

    /**
     * 创建
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void print(String businessId, String businessNo, String businessType) {
        if (StringUtils.isBlank(businessId)) {
            throw new BizException("打印错误");
        }
        boolean limited = false;
        PrintLimit printLimit = printLimitService.getById(businessType);
        if (printLimit != null) {
            if (PrintLimitTypeConst.LIMIT_N.equals(printLimit.getLimitType())) {
                limited = true;
            }
            if (PrintLimitTypeConst.LIMIT_1.equals(printLimit.getLimitType())) {
                limited = true;
            }
        }
        Date printTime = new Date();
        // PrintBusinessStat
        PrintBusinessStat printBusiness = printBusinessStatService.getById(businessId);
        if (printBusiness != null) {
            printAgain(businessId, businessNo, businessType, userSupport.getUserId(), printTime, limited);
        } else {
            firstPrint(businessId, businessNo, businessType, userSupport.getUserId(), printTime, limited);
        }

        // PrintRecord
        PrintRecord record = new PrintRecord();
        record.setId(IdHelper.snowflakeId());
        record.setPrinterId(userSupport.getUserId());
        record.setPrintTime(printTime);
        record.setBusinessId(businessId);
        record.setBusinessType(businessType);
        record.setBusinessNo(businessNo);
        save(record);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void printTax(String businessId, String businessNo, String businessType) {
        if (StringUtils.isBlank(businessId)) {
            throw new BizException("打印错误");
        }
        businessId = businessId + "-SW";
        Date printTime = new Date();
        // PrintBusinessStat
        PrintBusinessStat printBusiness = printBusinessStatService.getById(businessId);
        if (printBusiness != null) {
            printAgain(businessId, businessNo, businessType, userSupport.getUserId(), printTime, false);
        } else {
            firstPrint(businessId, businessNo, businessType, userSupport.getUserId(), printTime, false);
        }
        // PrintRecord
        PrintRecord record = new PrintRecord();
        record.setId(IdHelper.snowflakeId());
        record.setPrinterId(userSupport.getUserId());
        record.setPrintTime(printTime);
        record.setBusinessId(businessId);
        record.setBusinessType(businessType);
        record.setBusinessNo(businessNo);
        save(record);
    }

    private void firstPrint(String businessId, String businessNo, String businessType, String userId, Date printTime, boolean limited) {
        PrintBusinessStat printBusiness = new PrintBusinessStat();
        printBusiness.setBusinessId(businessId);
        printBusiness.setBusinessNo(businessNo);
        printBusiness.setBusinessType(businessType);
        printBusiness.setPrinterId(userId);
        printBusiness.setPrintTime(printTime);
        printBusiness.setPrintCount(1);
        printBusiness.setPrintStatus(limited ? PrintStatusConst.LIMITED : PrintStatusConst.PRINTABLE);
        printBusinessStatService.save(printBusiness);
    }

    private void printAgain(String businessId, String businessNo, String businessType, String userId, Date printTime, boolean limited) {
        printApplyService.updatePrintFlag(businessId, businessType, userId);
        UpdateWrapper<PrintBusinessStat> uw = new UpdateWrapper<>();
        uw.setSql("print_count = print_count + " + 1);
        uw.lambda().set(PrintBusinessStat::getPrintStatus, limited ? PrintStatusConst.LIMITED : PrintStatusConst.PRINTABLE);
        uw.lambda().set(PrintBusinessStat::getPrinterId, userId);
        uw.lambda().set(PrintBusinessStat::getPrintTime, printTime);
        uw.lambda().eq(PrintBusinessStat::getBusinessId, businessId);
        uw.lambda().eq(PrintBusinessStat::getBusinessType, businessType);
        printBusinessStatService.update(new PrintBusinessStat(), uw);
    }

}